{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 日期数据基础概念\n",
    "\n",
    "在学习Pandas的日期时间处理功能之前，我们需要先了解日期数据的基础概念。本教程将介绍Python中的datetime模块、常见的日期格式，以及Pandas中的日期时间数据类型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from datetime import datetime, date, time, timedelta\n",
    "import time as time_module\n",
    "from dateutil import parser"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Python datetime模块基础\n",
    "\n",
    "Python的datetime模块提供了处理日期和时间的基本类型。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.1 date对象 - 只包含日期"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "今天的日期: 2025-11-17\n",
      "日期类型: <class 'datetime.date'>\n",
      "生日: 1990-05-15\n",
      "年: 1990\n",
      "月: 5\n",
      "日: 15\n"
     ]
    }
   ],
   "source": [
    "# 创建date对象\n",
    "today = date.today()\n",
    "print(f\"今天的日期: {today}\")\n",
    "print(f\"日期类型: {type(today)}\")\n",
    "\n",
    "# 手动创建特定日期\n",
    "birthday = date(1990, 5, 15)\n",
    "print(f\"生日: {birthday}\")\n",
    "\n",
    "# 访问日期组件\n",
    "print(f\"年: {birthday.year}\")\n",
    "print(f\"月: {birthday.month}\")\n",
    "print(f\"日: {birthday.day}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2 time对象 - 只包含时间"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "datetime.now() 返回: 2025-11-17 08:36:38.165885\n",
      "类型: <class 'datetime.datetime'>\n",
      "当前时间: 08:36:38.165885\n",
      "会议时间: 14:30:00\n",
      "时间类型: <class 'datetime.time'>\n",
      "小时: 14\n",
      "分钟: 30\n",
      "秒: 0\n",
      "精确时间: 14:30:15.123456\n",
      "微秒: 123456\n"
     ]
    }
   ],
   "source": [
    "# 创建time对象\n",
    "meeting_time = time(14, 30, 0)  # 14:30:00\n",
    "\n",
    "# datetime.now() 返回的是当前的本地日期和时间，类型为 datetime.datetime\n",
    "now_dt = datetime.now()\n",
    "print(f\"datetime.now() 返回: {now_dt}\")\n",
    "print(f\"类型: {type(now_dt)}\")\n",
    "current_time = now_dt.time()\n",
    "print(f\"当前时间: {current_time}\")\n",
    "\n",
    "print(f\"会议时间: {meeting_time}\")\n",
    "print(f\"时间类型: {type(meeting_time)}\")\n",
    "\n",
    "# 访问时间组件\n",
    "print(f\"小时: {meeting_time.hour}\")\n",
    "print(f\"分钟: {meeting_time.minute}\")\n",
    "print(f\"秒: {meeting_time.second}\")\n",
    "\n",
    "# 包含微秒的时间\n",
    "precise_time = time(14, 30, 15, 123456)\n",
    "print(f\"精确时间: {precise_time}\")\n",
    "print(f\"微秒: {precise_time.microsecond}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3 datetime对象 - 包含日期和时间"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当前时间: 2025-11-17 08:36:52.126274\n",
      "datetime类型: <class 'datetime.datetime'>\n",
      "活动时间: 2023-12-25 18:30:00\n",
      "年: 2023\n",
      "月: 12\n",
      "日: 25\n",
      "小时: 18\n",
      "分钟: 30\n",
      "星期几: 0\n"
     ]
    }
   ],
   "source": [
    "# 创建datetime对象\n",
    "now = datetime.now()\n",
    "print(f\"当前时间: {now}\")\n",
    "print(f\"datetime类型: {type(now)}\")\n",
    "\n",
    "# 手动创建特定的datetime\n",
    "event_time = datetime(2023, 12, 25, 18, 30, 0)\n",
    "print(f\"活动时间: {event_time}\")\n",
    "\n",
    "# 访问datetime组件\n",
    "print(f\"年: {event_time.year}\")\n",
    "print(f\"月: {event_time.month}\")\n",
    "print(f\"日: {event_time.day}\")\n",
    "print(f\"小时: {event_time.hour}\")\n",
    "print(f\"分钟: {event_time.minute}\")\n",
    "print(f\"星期几: {event_time.weekday()}\")  # 0=Monday, 6=Sunday"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.4 timedelta对象 - 时间差"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "时间差: 7 days, 3:30:00\n",
      "总天数: 7\n",
      "总秒数: 617400.0\n",
      "开始时间: 2023-01-01 10:00:00\n",
      "结束时间: 2023-01-08 13:30:00\n",
      "时间差: 7 days, 3:30:00\n",
      "差值类型: <class 'datetime.timedelta'>\n"
     ]
    }
   ],
   "source": [
    "# 创建timedelta对象\n",
    "duration = timedelta(days=7, hours=3, minutes=30)\n",
    "print(f\"时间差: {duration}\")\n",
    "print(f\"总天数: {duration.days}\")\n",
    "print(f\"总秒数: {duration.total_seconds()}\")\n",
    "\n",
    "# 时间运算\n",
    "start_time = datetime(2023, 1, 1, 10, 0, 0)\n",
    "end_time = start_time + duration\n",
    "print(f\"开始时间: {start_time}\")\n",
    "print(f\"结束时间: {end_time}\")\n",
    "\n",
    "# 计算两个时间的差值\n",
    "time_diff = end_time - start_time\n",
    "print(f\"时间差: {time_diff}\")\n",
    "print(f\"差值类型: {type(time_diff)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 时间戳概念\n",
    "\n",
    "时间戳是从1970年1月1日00:00:00 UTC开始计算的秒数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当前时间戳: 1763340107.367609\n",
      "datetime: 2023-06-15 12:30:00\n",
      "对应时间戳: 1686803400.0\n",
      "从时间戳转回: 2023-06-15 12:30:00\n",
      "Unix纪元时间: 1970-01-01 00:00:00\n",
      "纪元时间戳: -28800.0\n"
     ]
    }
   ],
   "source": [
    "# 获取当前时间戳\n",
    "current_timestamp = time_module.time()\n",
    "print(f\"当前时间戳: {current_timestamp}\")\n",
    "\n",
    "# datetime转时间戳\n",
    "dt = datetime(2023, 6, 15, 12, 30, 0)\n",
    "timestamp = dt.timestamp()\n",
    "print(f\"datetime: {dt}\")\n",
    "print(f\"对应时间戳: {timestamp}\")\n",
    "\n",
    "# 时间戳转datetime\n",
    "dt_from_timestamp = datetime.fromtimestamp(timestamp)\n",
    "print(f\"从时间戳转回: {dt_from_timestamp}\")\n",
    "\n",
    "# Unix纪元时间\n",
    "# epoch 是一个 datetime 对象，表示“纪元时间点”（1970-01-01 00:00:00）。\n",
    "epoch = datetime(1970, 1, 1)\n",
    "print(f\"Unix纪元时间: {epoch}\")\n",
    "# epoch.timestamp() 得到的是 从纪元时间到 epoch 之间的秒数。\n",
    "# 对应“纪元时间点”本身，时间戳理论上就是 0（受本地时区影响可能会有偏移）。\n",
    "print(f\"纪元时间戳: {epoch.timestamp()}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. 常见日期格式\n",
    "\n",
    "了解不同的日期格式对于数据处理非常重要。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.1 ISO 8601格式（国际标准）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ISO 8601格式示例:\n",
      "2023-06-15                     -> 2023-06-15 00:00:00\n",
      "2023-06-15T14:30:00            -> 2023-06-15 14:30:00\n",
      "2023-06-15T14:30:00Z           -> 2023-06-15 14:30:00+00:00\n",
      "2023-06-15T14:30:00+08:00      -> 2023-06-15 14:30:00+08:00\n",
      "2023-06-15T14:30:00.123456     -> 2023-06-15 14:30:00.123456\n"
     ]
    }
   ],
   "source": [
    "from dateutil import parser\n",
    "\n",
    "# ISO 8601格式示例，涵盖不同的日期和时间表示方式\n",
    "iso_formats = [\n",
    "    \"2023-06-15\",                    # 仅日期\n",
    "    \"2023-06-15T14:30:00\",           # 日期和时间\n",
    "    \"2023-06-15T14:30:00Z\",          # UTC时间（以Z结尾）\n",
    "    \"2023-06-15T14:30:00+08:00\",     # 带有东八区时区偏移\n",
    "    \"2023-06-15T14:30:00.123456\",    # 带有微秒的时间\n",
    "]\n",
    "\n",
    "print(\"ISO 8601格式示例:\")\n",
    "for fmt in iso_formats:\n",
    "    try:\n",
    "        # 使用dateutil.parser.parse自动解析ISO 8601字符串为datetime对象\n",
    "        parsed = parser.parse(fmt)\n",
    "        # {fmt:30}\n",
    "        # 把变量 fmt 按宽度 30 个字符来显示，不足会在右侧用空格补齐。\n",
    "        # 这样的目的是：让所有输出的“格式字符串”在终端左边对齐，看起来整齐。\n",
    "        print(f\"{fmt:30} -> {parsed}\")\n",
    "    except Exception as e:\n",
    "        # 解析失败时输出提示信息\n",
    "        print(f\"{fmt:30} -> 解析失败\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2 常见的地区格式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "不同地区的日期格式:\n",
      "2023/06/15           -> 2023-06-15\n",
      "06/15/2023           -> 2023-06-15\n",
      "15/06/2023           -> 2023-06-15\n",
      "15-Jun-2023          -> 2023-06-15\n",
      "June 15, 2023        -> 2023-06-15\n",
      "2023年6月15日           -> 解析失败\n"
     ]
    }
   ],
   "source": [
    "# 不同地区的日期格式\n",
    "regional_formats = [\n",
    "    \"2023/06/15\",        # 通用格式\n",
    "    \"06/15/2023\",        # 美式格式 (MM/DD/YYYY)\n",
    "    \"15/06/2023\",        # 欧式格式 (DD/MM/YYYY)\n",
    "    \"15-Jun-2023\",       # 月份缩写\n",
    "    \"June 15, 2023\",     # 英文格式\n",
    "    \"2023年6月15日\",      # 中文格式\n",
    "]\n",
    "\n",
    "print(\"不同地区的日期格式:\")\n",
    "for fmt in regional_formats:\n",
    "    try:\n",
    "        parsed = parser.parse(fmt)\n",
    "        print(f\"{fmt:20} -> {parsed.date()}\")\n",
    "    except:\n",
    "        print(f\"{fmt:20} -> 解析失败\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3 格式化字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "示例时间: 2023-06-15 14:30:45\n",
      "\n",
      "格式化代码示例:\n",
      "%Y   (四位年份           ) -> 2023\n",
      "%y   (两位年份           ) -> 23\n",
      "%m   (月份(01-12)      ) -> 06\n",
      "%B   (月份全名           ) -> June\n",
      "%b   (月份缩写           ) -> Jun\n",
      "%d   (日期(01-31)      ) -> 15\n",
      "%H   (小时(00-23)      ) -> 14\n",
      "%I   (小时(01-12)      ) -> 02\n",
      "%M   (分钟(00-59)      ) -> 30\n",
      "%S   (秒(00-59)       ) -> 45\n",
      "%A   (星期全名           ) -> Thursday\n",
      "%a   (星期缩写           ) -> Thu\n",
      "%w   (星期数字(0=Sunday) ) -> 4\n"
     ]
    }
   ],
   "source": [
    "# 常用的格式化代码\n",
    "dt = datetime(2023, 6, 15, 14, 30, 45)\n",
    "\n",
    "format_codes = {\n",
    "    '%Y': '四位年份',\n",
    "    '%y': '两位年份', \n",
    "    '%m': '月份(01-12)',\n",
    "    '%B': '月份全名',\n",
    "    '%b': '月份缩写',\n",
    "    '%d': '日期(01-31)',\n",
    "    '%H': '小时(00-23)',\n",
    "    '%I': '小时(01-12)',\n",
    "    '%M': '分钟(00-59)',\n",
    "    '%S': '秒(00-59)',\n",
    "    '%A': '星期全名',\n",
    "    '%a': '星期缩写',\n",
    "    '%w': '星期数字(0=Sunday)',\n",
    "}\n",
    "\n",
    "print(f\"示例时间: {dt}\")\n",
    "print(\"\\n格式化代码示例:\")\n",
    "# 遍历格式化代码字典，演示每种格式化效果\n",
    "for code, description in format_codes.items():\n",
    "    formatted = dt.strftime(code)  # 使用strftime按当前代码格式化日期时间\n",
    "    print(f\"{code:4} ({description:15}) -> {formatted}\")  # 打印格式化代码、描述和结果"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.4 常用格式化模式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 常用的完整格式化模式\n",
    "patterns = {\n",
    "    '%Y-%m-%d': 'ISO日期格式',\n",
    "    '%Y-%m-%d %H:%M:%S': 'ISO日期时间格式',\n",
    "    '%d/%m/%Y': '欧式日期格式',\n",
    "    '%m/%d/%Y': '美式日期格式',\n",
    "    '%B %d, %Y': '英文长格式',\n",
    "    '%Y年%m月%d日': '中文日期格式',\n",
    "    '%A, %B %d, %Y': '完整英文格式',\n",
    "    '%Y-%m-%d %H:%M:%S.%f': '带微秒格式',\n",
    "}\n",
    "\n",
    "print(f\"示例时间: {dt}\")\n",
    "print(\"\\n常用格式化模式:\")\n",
    "for pattern, description in patterns.items():\n",
    "    try:\n",
    "        formatted = dt.strftime(pattern)\n",
    "        print(f\"{description:15} -> {formatted}\")\n",
    "    except:\n",
    "        print(f\"{description:15} -> 格式化失败\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.5 strftime() 方法详解\n",
    "\n",
    "`strftime()` 是将 `datetime` 对象格式化为字符串的核心方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# strftime() 基本用法\n",
    "dt = datetime(2023, 6, 15, 14, 30, 45)\n",
    "print(f\"原始datetime对象: {dt}\")\n",
    "print()\n",
    "\n",
    "# 基本格式化\n",
    "print(\"=== 基本日期格式 ===\")\n",
    "print(f\"标准日期: {dt.strftime('%Y-%m-%d')}\")\n",
    "print(f\"美式日期: {dt.strftime('%m/%d/%Y')}\")\n",
    "print(f\"欧式日期: {dt.strftime('%d/%m/%Y')}\")\n",
    "print(f\"中文日期: {dt.strftime('%Y年%m月%d日')}\")\n",
    "\n",
    "print(\"\\n=== 基本时间格式 ===\")\n",
    "print(f\"24小时制: {dt.strftime('%H:%M:%S')}\")\n",
    "print(f\"12小时制: {dt.strftime('%I:%M:%S %p')}\")\n",
    "print(f\"只显示时分: {dt.strftime('%H:%M')}\")\n",
    "\n",
    "print(\"\\n=== 完整日期时间格式 ===\")\n",
    "print(f\"ISO格式: {dt.strftime('%Y-%m-%d %H:%M:%S')}\")\n",
    "print(f\"友好格式: {dt.strftime('%B %d, %Y at %I:%M %p')}\")\n",
    "print(f\"紧凑格式: {dt.strftime('%Y%m%d_%H%M%S')}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 星期和月份的文本表示\n",
    "print(\"=== 星期表示 ===\")\n",
    "print(f\"星期全名: {dt.strftime('%A')}\")\n",
    "print(f\"星期缩写: {dt.strftime('%a')}\")\n",
    "print(f\"星期数字: {dt.strftime('%w')}\")  # 0=Sunday, 6=Saturday\n",
    "\n",
    "print(\"\\n=== 月份表示 ===\")\n",
    "print(f\"月份全名: {dt.strftime('%B')}\")\n",
    "print(f\"月份缩写: {dt.strftime('%b')}\")\n",
    "print(f\"月份数字: {dt.strftime('%m')}\")\n",
    "\n",
    "print(\"\\n=== 年份表示 ===\")\n",
    "print(f\"四位年份: {dt.strftime('%Y')}\")\n",
    "print(f\"两位年份: {dt.strftime('%y')}\")\n",
    "\n",
    "print(\"\\n=== 其他有用的格式 ===\")\n",
    "print(f\"一年中第几天: {dt.strftime('%j')}\")\n",
    "print(f\"一年中第几周: {dt.strftime('%U')}\")  # 以Sunday为周首\n",
    "print(f\"一年中第几周: {dt.strftime('%W')}\")  # 以Monday为周首"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 实际应用场景示例\n",
    "print(\"=== 实际应用场景 ===\")\n",
    "\n",
    "# 1. 日志文件命名\n",
    "log_filename = dt.strftime(\"log_%Y%m%d_%H%M%S.txt\")\n",
    "print(f\"日志文件名: {log_filename}\")\n",
    "\n",
    "# 2. 数据库查询友好格式\n",
    "db_format = dt.strftime(\"%Y-%m-%d %H:%M:%S\")\n",
    "print(f\"数据库格式: {db_format}\")\n",
    "\n",
    "# 3. 用户友好的显示格式\n",
    "user_friendly = dt.strftime(\"%A, %B %d, %Y\")\n",
    "print(f\"用户友好格式: {user_friendly}\")\n",
    "\n",
    "# 4. 文件夹按日期组织\n",
    "folder_structure = dt.strftime(\"%Y/%m/%d\")\n",
    "print(f\"文件夹结构: {folder_structure}\")\n",
    "\n",
    "# 5. 报表标题格式\n",
    "report_title = dt.strftime(\"销售报表 - %Y年%m月\")\n",
    "print(f\"报表标题: {report_title}\")\n",
    "\n",
    "# 6. API时间戳格式\n",
    "api_timestamp = dt.strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n",
    "print(f\"API时间戳: {api_timestamp}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# strftime() 与 strptime() 的对比\n",
    "print(\"=== strftime() vs strptime() ===\")\n",
    "\n",
    "# strftime(): datetime对象 → 字符串\n",
    "original_dt = datetime(2023, 6, 15, 14, 30, 45)\n",
    "formatted_string = original_dt.strftime(\"%Y-%m-%d %H:%M:%S\")\n",
    "print(f\"strftime() - 格式化输出:\")\n",
    "print(f\"  {original_dt} → '{formatted_string}'\")\n",
    "\n",
    "# strptime(): 字符串 → datetime对象\n",
    "date_string = \"2023-06-15 14:30:45\"\n",
    "parsed_dt = datetime.strptime(date_string, \"%Y-%m-%d %H:%M:%S\")\n",
    "print(f\"\\nstrptime() - 解析输入:\")\n",
    "print(f\"  '{date_string}' → {parsed_dt}\")\n",
    "\n",
    "# 往返转换示例\n",
    "print(f\"\\n=== 往返转换验证 ===\")\n",
    "print(f\"原始: {original_dt}\")\n",
    "print(f\"格式化: {formatted_string}\")\n",
    "print(f\"解析回: {parsed_dt}\")\n",
    "print(f\"是否相等: {original_dt == parsed_dt}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Pandas中的strftime()应用\n",
    "print(\"=== Pandas中的strftime()应用 ===\")\n",
    "\n",
    "# 创建包含日期的DataFrame\n",
    "dates = pd.date_range('2023-06-01', periods=5, freq='D')\n",
    "df = pd.DataFrame({\n",
    "    'date': dates,\n",
    "    'value': [100, 150, 120, 180, 200]\n",
    "})\n",
    "\n",
    "print(\"原始DataFrame:\")\n",
    "print(df)\n",
    "\n",
    "# 使用dt.strftime()格式化整列日期\n",
    "df['date_formatted'] = df['date'].dt.strftime('%Y年%m月%d日')\n",
    "df['weekday'] = df['date'].dt.strftime('%A')\n",
    "df['month_year'] = df['date'].dt.strftime('%Y-%m')\n",
    "\n",
    "print(\"\\n添加格式化列后:\")\n",
    "print(df)\n",
    "\n",
    "# 在Pandas中常用的格式化场景\n",
    "print(f\"\\n=== 常用场景 ===\")\n",
    "print(\"1. 按月分组:\")\n",
    "monthly_summary = df.groupby('month_year')['value'].sum()\n",
    "print(monthly_summary)\n",
    "\n",
    "print(\"\\n2. 创建文件名:\")\n",
    "for idx, row in df.iterrows():\n",
    "    filename = f\"data_{row['date'].strftime('%Y%m%d')}.csv\"\n",
    "    print(f\"  {filename}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### strftime() 格式代码速查表\n",
    "\n",
    "| 代码 | 含义 | 示例输出 |\n",
    "|------|------|----------|\n",
    "| **日期相关** |\n",
    "| `%Y` | 4位年份 | 2023 |\n",
    "| `%y` | 2位年份 | 23 |\n",
    "| `%m` | 月份(01-12) | 06 |\n",
    "| `%B` | 月份全名 | June |\n",
    "| `%b` | 月份缩写 | Jun |\n",
    "| `%d` | 日期(01-31) | 15 |\n",
    "| `%j` | 一年中第几天(001-366) | 166 |\n",
    "| **时间相关** |\n",
    "| `%H` | 小时(00-23) | 14 |\n",
    "| `%I` | 小时(01-12) | 02 |\n",
    "| `%M` | 分钟(00-59) | 30 |\n",
    "| `%S` | 秒(00-59) | 45 |\n",
    "| `%f` | 微秒(000000-999999) | 123456 |\n",
    "| `%p` | AM/PM | PM |\n",
    "| **星期相关** |\n",
    "| `%A` | 星期全名 | Thursday |\n",
    "| `%a` | 星期缩写 | Thu |\n",
    "| `%w` | 星期数字(0=Sunday) | 4 |\n",
    "| `%U` | 一年中第几周(Sunday为周首) | 24 |\n",
    "| `%W` | 一年中第几周(Monday为周首) | 24 |\n",
    "| **其他** |\n",
    "| `%c` | 完整日期时间 | Thu Jun 15 14:30:45 2023 |\n",
    "| `%x` | 本地日期格式 | 06/15/23 |\n",
    "| `%X` | 本地时间格式 | 14:30:45 |\n",
    "| `%%` | 字面量% | % |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Pandas中的日期时间数据类型\n",
    "\n",
    "Pandas扩展了Python的datetime功能，提供了更强大的日期时间处理能力。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1 Timestamp对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建Pandas Timestamp\n",
    "ts = pd.Timestamp('2023-06-15 14:30:00')\n",
    "print(f\"Pandas Timestamp: {ts}\")\n",
    "print(f\"类型: {type(ts)}\")\n",
    "\n",
    "# 从不同输入创建Timestamp\n",
    "timestamps = [\n",
    "    pd.Timestamp('2023-06-15'),\n",
    "    pd.Timestamp(2023, 6, 15),\n",
    "    pd.Timestamp(datetime(2023, 6, 15)),\n",
    "    pd.Timestamp(1686830400, unit='s'),  # 从时间戳创建\n",
    "]\n",
    "\n",
    "print(\"\\n不同方式创建的Timestamp:\")\n",
    "for i, ts in enumerate(timestamps, 1):\n",
    "    print(f\"{i}. {ts}\")\n",
    "\n",
    "# Timestamp的属性\n",
    "ts = pd.Timestamp('2023-06-15 14:30:45')\n",
    "print(f\"\\nTimestamp属性:\")\n",
    "print(f\"年: {ts.year}\")\n",
    "print(f\"月: {ts.month}\")\n",
    "print(f\"日: {ts.day}\")\n",
    "print(f\"小时: {ts.hour}\")\n",
    "print(f\"分钟: {ts.minute}\")\n",
    "print(f\"秒: {ts.second}\")\n",
    "print(f\"星期几: {ts.dayofweek}\")\n",
    "print(f\"一年中的第几天: {ts.dayofyear}\")\n",
    "print(f\"季度: {ts.quarter}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2 Timedelta对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建Pandas Timedelta\n",
    "td = pd.Timedelta('2 days 3 hours')\n",
    "print(f\"Pandas Timedelta: {td}\")\n",
    "print(f\"类型: {type(td)}\")\n",
    "\n",
    "# 不同方式创建Timedelta\n",
    "timedeltas = [\n",
    "    pd.Timedelta(days=2),\n",
    "    pd.Timedelta('1 hour 30 minutes'),\n",
    "    pd.Timedelta(hours=1.5),\n",
    "    pd.Timedelta('0 days 01:30:00'),\n",
    "    pd.Timedelta(seconds=3600),\n",
    "]\n",
    "\n",
    "print(\"\\n不同方式创建的Timedelta:\")\n",
    "for i, td in enumerate(timedeltas, 1):\n",
    "    print(f\"{i}. {td}\")\n",
    "\n",
    "# Timedelta的属性和方法\n",
    "td = pd.Timedelta('2 days 3 hours 30 minutes')\n",
    "print(f\"\\nTimedelta属性:\")\n",
    "print(f\"天数: {td.days}\")\n",
    "print(f\"秒数: {td.seconds}\")\n",
    "print(f\"总秒数: {td.total_seconds()}\")\n",
    "print(f\"组件: {td.components}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.3 Period对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建Period对象\n",
    "period = pd.Period('2023-06', freq='M')\n",
    "print(f\"Period对象: {period}\")\n",
    "print(f\"类型: {type(period)}\")\n",
    "\n",
    "# 不同频率的Period\n",
    "periods = [\n",
    "    pd.Period('2023', freq='Y'),      # 年\n",
    "    pd.Period('2023-Q2', freq='Q'),   # 季度\n",
    "    pd.Period('2023-06', freq='M'),   # 月\n",
    "    pd.Period('2023-06-15', freq='D'), # 日\n",
    "    pd.Period('2023-06-15 14', freq='H'), # 小时\n",
    "]\n",
    "\n",
    "print(\"\\n不同频率的Period:\")\n",
    "for period in periods:\n",
    "    print(f\"{period.freq} -> {period}\")\n",
    "\n",
    "# Period的运算\n",
    "p = pd.Period('2023-06', freq='M')\n",
    "print(f\"\\nPeriod运算:\")\n",
    "print(f\"原始Period: {p}\")\n",
    "print(f\"下个月: {p + 1}\")\n",
    "print(f\"上个月: {p - 1}\")\n",
    "print(f\"开始时间: {p.start_time}\")\n",
    "print(f\"结束时间: {p.end_time}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. 数据类型转换\n",
    "\n",
    "了解如何在不同的日期时间类型之间转换。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Python datetime与Pandas Timestamp的转换\n",
    "py_dt = datetime(2023, 6, 15, 14, 30, 0)\n",
    "pd_ts = pd.Timestamp(py_dt)\n",
    "\n",
    "print(f\"Python datetime: {py_dt} (类型: {type(py_dt)})\")\n",
    "print(f\"Pandas Timestamp: {pd_ts} (类型: {type(pd_ts)})\")\n",
    "\n",
    "# 转换回Python datetime\n",
    "back_to_py = pd_ts.to_pydatetime()\n",
    "print(f\"转换回Python datetime: {back_to_py} (类型: {type(back_to_py)})\")\n",
    "\n",
    "# Timestamp与Period的转换\n",
    "ts = pd.Timestamp('2023-06-15')\n",
    "period = ts.to_period('M')  # 转换为月周期\n",
    "print(f\"\\nTimestamp: {ts}\")\n",
    "print(f\"转换为Period: {period}\")\n",
    "\n",
    "# Period转换回Timestamp\n",
    "back_to_ts = period.to_timestamp()\n",
    "print(f\"Period转换回Timestamp: {back_to_ts}\")\n",
    "\n",
    "# 时间戳转换\n",
    "timestamp = 1686830400\n",
    "from_timestamp = pd.Timestamp(timestamp, unit='s')\n",
    "print(f\"\\n时间戳 {timestamp} 转换为: {from_timestamp}\")\n",
    "print(f\"转换回时间戳: {from_timestamp.timestamp()}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. 日期时间数据的存储和性能\n",
    "\n",
    "了解Pandas中日期时间数据的内部存储机制。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建日期时间Series\n",
    "dates = pd.date_range('2023-01-01', periods=5, freq='D')\n",
    "print(f\"日期范围: {dates}\")\n",
    "print(f\"数据类型: {dates.dtype}\")\n",
    "print(f\"内部值: {dates.values}\")\n",
    "\n",
    "# 查看内存使用\n",
    "df = pd.DataFrame({\n",
    "    'date_str': ['2023-01-01', '2023-01-02', '2023-01-03'] * 1000,\n",
    "    'date_dt': pd.date_range('2023-01-01', periods=3000, freq='D')\n",
    "})\n",
    "\n",
    "print(f\"\\n数据框内存使用:\")\n",
    "print(df.info(memory_usage='deep'))\n",
    "\n",
    "# 精度和范围\n",
    "print(f\"\\nTimestamp的范围:\")\n",
    "print(f\"最小值: {pd.Timestamp.min}\")\n",
    "print(f\"最大值: {pd.Timestamp.max}\")\n",
    "print(f\"分辨率: 纳秒级\")\n",
    "\n",
    "# 纳秒精度示例\n",
    "precise_ts = pd.Timestamp('2023-06-15 14:30:00.123456789')\n",
    "print(f\"\\n高精度时间戳: {precise_ts}\")\n",
    "print(f\"纳秒: {precise_ts.nanosecond}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n",
    "\n",
    "本教程介绍了日期数据的基础概念：\n",
    "\n",
    "1. **Python datetime模块**：\n",
    "   - `date`：只包含日期\n",
    "   - `time`：只包含时间\n",
    "   - `datetime`：包含日期和时间\n",
    "   - `timedelta`：时间差\n",
    "\n",
    "2. **时间戳**：从Unix纪元开始的秒数表示\n",
    "\n",
    "3. **常见日期格式**：\n",
    "   - ISO 8601标准格式\n",
    "   - 地区性格式（美式、欧式、中文等）\n",
    "   - 格式化字符串代码\n",
    "\n",
    "4. **Pandas日期时间类型**：\n",
    "   - `Timestamp`：增强的datetime对象\n",
    "   - `Timedelta`：增强的timedelta对象\n",
    "   - `Period`：时间周期对象\n",
    "\n",
    "5. **数据类型转换**：不同类型间的相互转换\n",
    "\n",
    "6. **存储和性能**：内部存储机制和精度范围\n",
    "\n",
    "掌握这些基础概念后，我们就可以深入学习Pandas的日期时间处理功能了。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "ml311",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
